1 package org.apache.maven.surefire.junitcore;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.surefire.common.junit4.Notifier;
23 import org.apache.maven.surefire.junitcore.pc.ParallelComputer;
24 import org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder;
25 import org.apache.maven.surefire.report.ConsoleLogger;
26 import org.apache.maven.surefire.testset.TestSetFailedException;
27 import org.apache.maven.surefire.util.TestsToRun;
28 import org.junit.Ignore;
29 import org.junit.runner.Computer;
30 import org.junit.runner.Description;
31 import org.junit.runner.Request;
32 import org.junit.runner.Result;
33 import org.junit.runner.manipulation.Filter;
34 import org.junit.runner.notification.RunListener;
35 import org.junit.runner.notification.StoppedByUserException;
36
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.Queue;
40
41 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.createDescription;
42 import static org.apache.maven.surefire.common.junit4.JUnit4Reflector.createIgnored;
43 import static org.apache.maven.surefire.common.junit4.JUnit4RunListener.rethrowAnyTestMechanismFailures;
44
45
46
47
48
49
50 final class JUnitCoreWrapper
51 {
52 private final Notifier notifier;
53 private final JUnitCoreParameters jUnitCoreParameters;
54 private final ConsoleLogger logger;
55 private final boolean failFast;
56
57 JUnitCoreWrapper( Notifier notifier, JUnitCoreParameters jUnitCoreParameters, ConsoleLogger logger,
58 boolean failFast )
59 {
60 this.notifier = notifier;
61 this.jUnitCoreParameters = jUnitCoreParameters;
62 this.logger = logger;
63 this.failFast = failFast;
64 }
65
66 void execute( TestsToRun testsToRun, Filter filter )
67 throws TestSetFailedException
68 {
69 execute( testsToRun, Collections.<RunListener>emptyList(), filter );
70 }
71
72 void execute( TestsToRun testsToRun, Collection<RunListener> listeners, Filter filter )
73 throws TestSetFailedException
74 {
75 if ( testsToRun.allowEagerReading() )
76 {
77 executeEager( testsToRun, filter, listeners );
78 }
79 else
80 {
81 executeLazy( testsToRun, filter, listeners );
82 }
83 }
84
85 private JUnitCore createJUnitCore( final Notifier notifier, Collection<RunListener> listeners )
86 {
87 JUnitCore junitCore = new JUnitCore();
88
89
90 notifier.addListeners( listeners );
91
92 return junitCore;
93 }
94
95 private void executeEager( TestsToRun testsToRun, Filter filter, Collection<RunListener> listeners )
96 throws TestSetFailedException
97 {
98 JUnitCore junitCore = createJUnitCore( notifier, listeners );
99 Class<?>[] tests = testsToRun.getLocatedClasses();
100 Computer computer = createComputer();
101 createRequestAndRun( filter, computer, junitCore.withReportedTests( tests ), tests );
102 }
103
104 private void executeLazy( TestsToRun testsToRun, Filter filter, Collection<RunListener> listeners )
105 throws TestSetFailedException
106 {
107 JUnitCore junitCore = createJUnitCore( notifier, listeners );
108
109 for ( Class<?> clazz : testsToRun )
110 {
111 Computer computer = createComputer();
112 createRequestAndRun( filter, computer, junitCore.withReportedTests( clazz ), clazz );
113 }
114 }
115
116 private void createRequestAndRun( Filter filter, Computer computer, JUnitCore junitCore, Class<?>... classesToRun )
117 throws TestSetFailedException
118 {
119 Request req = Request.classes( computer, classesToRun );
120 if ( filter != null )
121 {
122 req = new FilteringRequest( req, filter );
123 if ( req.getRunner() == null )
124 {
125
126 return;
127 }
128 }
129
130 Result run = junitCore.run( req.getRunner() );
131 rethrowAnyTestMechanismFailures( run );
132
133 if ( computer instanceof ParallelComputer )
134 {
135 String timeoutMessage = ( (ParallelComputer) computer ).describeElapsedTimeout();
136 if ( timeoutMessage.length() != 0 )
137 {
138 throw new TestSetFailedException( timeoutMessage );
139 }
140 }
141 }
142
143 private Computer createComputer()
144 {
145 return jUnitCoreParameters.isNoThreading()
146 ? Computer.serial()
147 : new ParallelComputerBuilder( logger, jUnitCoreParameters ).buildComputer();
148 }
149
150 private final class JUnitCore
151 extends org.apache.maven.surefire.junitcore.JUnitCore
152 {
153 private final JUnit47FailFastListener failFastListener;
154
155 JUnitCore()
156 {
157 super( notifier );
158 failFastListener = failFast ? new JUnit47FailFastListener( notifier ) : null;
159 if ( failFastListener != null )
160 {
161 notifier.addListener( failFastListener );
162 }
163 }
164
165 JUnitCore withReportedTests( Class<?>... tests )
166 {
167 Queue<String> stoppedTests = getRemainingTestClasses();
168 if ( stoppedTests != null )
169 {
170 for ( Class<?> test : tests )
171 {
172 stoppedTests.add( test.getName() );
173 }
174 }
175 return this;
176 }
177
178 @Override
179 @SuppressWarnings( "checkstyle:innerassignment" )
180 protected void afterException( Throwable e )
181 throws TestSetFailedException
182 {
183 if ( failFast && e instanceof StoppedByUserException )
184 {
185 Queue<String> stoppedTests = getRemainingTestClasses();
186 if ( stoppedTests != null )
187 {
188 String reason = e.getClass().getName();
189 Ignore reasonForSkippedTest = createIgnored( reason );
190 for ( String clazz; ( clazz = stoppedTests.poll() ) != null; )
191 {
192 Description skippedTest = createDescription( clazz, reasonForSkippedTest );
193 notifier.fireTestIgnored( skippedTest );
194 }
195 }
196 }
197 else
198 {
199 super.afterException( e );
200 }
201 }
202
203 @Override
204 protected void afterFinished()
205 {
206 Queue<String> stoppedTests = getRemainingTestClasses();
207 if ( stoppedTests != null )
208 {
209 stoppedTests.clear();
210 }
211 }
212
213 private Queue<String> getRemainingTestClasses()
214 {
215 return failFastListener == null ? null : failFastListener.getRemainingTestClasses();
216 }
217 }
218 }